<?php

/**
 * 分期乐JDK
 * @author chenyun
 */
namespace App\Service\VendorClient\ShopFenqileApi;
use App\Service\Code\Normal;
use App\Service\BaseService;
use App\Model\PssLogModel\MicroServiceLog;
use App\Service\HttpServer\Http;

class ShopFenqileApiClient extends BaseService
{
    protected $config = [];
    protected $bid    = null;
    private $account  = 'shopFenqile';
    //接口映射
    protected $routeMap = [
        'productQuery'          => 'fenqile.product.detail.get',
        'productAdd'            => 'fenqile.product.add',
        'productUpdate'         => 'fenqile.product.update',
        'productDetailUpdate'   => 'fenqile.product.update.detail',
        'productImageAdd'       => 'fenqile.product.add.image',
        'productImageDelete'    => 'fenqile.product.delete.image',
        'skuAdd'                => 'fenqile.sku.add',
        'skuUpdate'             => 'fenqile.sku.update',
        'skuQuantityUpdate'     => 'fenqile.sku.update.quantity',
        'skuDetailUpdate'       => 'fenqile.sku.update.detail',
        'featureGet'            => 'fenqile.product.feature.get',
        'productGet'            => 'fenqile.product.list.get',
        'productDelistUpdate'   => 'fenqile.product.update.delist',
        'productlistUpdate'     => 'fenqile.product.update.list',
        'productFeatureGet'     => 'fenqile.product.feature.get',
        'productCategoryGet'    => 'fenqile.category.authorize.get',
        'productBrandGet'       => 'fenqile.brand.authorize.get',
        'skuImageUpdate'        => 'fenqile.sku.update.image',
    ];
    public function __construct( $shop = NULL)
    {
        $this->config = @json_decode($shop['extends'], true);
        $this->bid    = $shop['bid'];
    }

    /**
     * 拉取商品分类
     * @param array $param
     */
    public function productCategoryGet()
    {
        $requestParam = [
            'method' => 'productCategoryGet',
            'data'   => [],
        ];
        return $this->execute($requestParam);
    }

    /**
     * 拉取商品品牌分类
     * @param array $param
     */
    public function productBrandGet()
    {
        $requestParam = [
            'method' => 'productBrandGet',
            'data'   => [],
        ];
        return $this->execute($requestParam);
    }
    /**
     * 拉取商品属性
     * @param array $param
     */
    public function productFeatureGet()
    {
        $requestParam = [
            'method' => 'productFeatureGet',
            'data'   => [],
        ];
        return $this->execute($requestParam);
    }
    
    /**
     * 拉取商品列表
     * @param array $param
     */
    public function productGet(array $param)
    {
        $page     = isset($param['page']) ? $param['page'] : 1 ;
        $pageSize = isset($param['pageSize']) ? $param['pageSize'] : 100 ;
        $requestParam = [
            'method' => 'productGet',
            'data'   => [
                "fields"     => "product_id",
                "page"       => $page,
                "page_size"  => $pageSize,
            ],
        ];
        return $this->execute($requestParam);
    }
    
    /**
     * 下架商品
     * @param array $param
     */
    public function productDelistUpdate(string $product_id)
    {
        $requestParam = [
            'method' => 'productDelistUpdate',
            'data'   => [
                "product_id"     => $product_id
            ],
        ];
        return $this->execute($requestParam);
    }
    
    /**
     * 上架商品
     * @param array $param
     */
    public function productlistUpdate(array $param)
    {
        $requestParam = [
            'method' => 'productlistUpdate',
            'data'   => [
                "product_id"     => $param['product_id']
            ],
        ];
        return $this->execute($requestParam);
    }
    
    /**
     * 更新feature基础数据
     * @param array $param
     */
    public function featureGet()
    {
        $requestParam = [
            'method' => 'featureGet',
            'data'   => [],
        ];
        return $this->execute($requestParam);
    }
    
    /**
     * 更新productQuery基础数据
     * @param array $param
     */
    public function productQuery( array $param)
    {
        $_extra = [
            "fields"    => 'sku_id,spec,pic_list,product_feature',
        ];
        $requestParam = [
            'method' => 'productQuery',
            'data'   => array_merge($param,$_extra),
        ];
        return $this->execute($requestParam);
    }
    
    /**
     * 更新productAdd基础数据
     * @param array $param
     */
    public function productAdd( array $param)
    {
        $_extra = [
            "brand_id"         => $this->config["brand_id"],
            "category_id_1"    => $this->config["category_id_1"],
            "category_id_2"    => $this->config["category_id_2"],
            "category_id_3"    => $this->config["category_id_3"],
            "feature"          => $this->config["feature"],
            "product_feature"  => $this->config["product_feature"]
        ];
        $requestParam = [
            'method' => 'productAdd',
            'data'   => array_merge($param,$_extra),
        ];
        return $this->execute($requestParam);
    }
    
    /**
     * 更新product基础数据
     * @param array $param
     */
    public function productUpdate( array $param)
    {
        $requestParam = [
            'method' => 'productUpdate',
            'data'   => $param,
        ];
        return $this->execute($requestParam);
    }
    
    /**
     * 更新product详情
     * @param array $param
     */
    public function productDetailUpdate( array $param)
    {
        $requestParam = [
            'method' => 'productDetailUpdate',
            'data'   => $param,
        ];
        return $this->execute($requestParam);
    }
    
    /**
     * 更新skuUpdate详情
     * @param array $param
     */
    public function skuUpdate( array $param)
    {
        $requestParam = [
            'method' => 'skuUpdate',
            'data'   => $param,
        ];
        return $this->execute($requestParam);
    }
    
    /**
     * 推送商品图片上传
     * @param array $param
     * @return mixed
     */
    public function productImageUpload(array $param) 
    {
        $product_id = $param['product_id'];
        $image = $param['image'];
        //获取上传图片的token
        $tokenInfo = $this->getUploadImageSourceToken();
        if($tokenInfo["code"] != Normal::SUC){
            return Normal::returnCode(Normal::FAIL, "没有获取到redirect_url地址");
        } 
        
        $redirect_url = $tokenInfo["data"];
        $result_upload = $this->uploadImageSource($redirect_url,$image);
        if( $result_upload["code"] != Normal::SUC ) {
            return $result_upload;
        }
        
        $pic_url = $result_upload["data"]["src"];
        $requestParam = [
            'method' => 'productImageAdd',
            'data'   => [
                'product_id'    => $product_id,
                'pic_url'       => $pic_url,
            ],
        ];
        $result = $this->execute($requestParam);
        if( $result["code"] != Normal::SUC ) {
            return Normal::returnCode(Normal::FAIL, "上次商品图片地址失败【{$result['msg']}】",$result);
        }
        return Normal::returnCode(Normal::SUC, "图片上传成功",$result);        
    }

    /**
     * 推送sku图片上传
     * @param array $param
     * @return mixed
     */
    public function skuImageUpload(array $param)
    {
        $sku_id     = $param['sku_id'];
        $image      = $param['image'];
        //获取上传图片的token
        $tokenInfo = $this->getUploadImageSourceToken();
        if($tokenInfo["code"] != Normal::SUC){
            return Normal::returnCode(Normal::FAIL, "没有获取到redirect_url地址");
        }
    
        $redirect_url = $tokenInfo["data"];
        $result_upload = $this->uploadImageSource($redirect_url,$image);
        $pic_url = $result_upload["data"]["src"];
        $requestParam = [
            'method' => 'skuImageUpdate',
            'data'   => [
                'sku_id'    => $sku_id,
                'pic_url'   => $pic_url,
            ],
        ];
        $result = $this->execute($requestParam);
        if( $result["code"] != Normal::SUC ) {
            return Normal::returnCode(Normal::FAIL, "上传sku图片地址失败【{$result['msg']}】",$result);
        }
        return Normal::returnCode(Normal::SUC, "图片上传成功",$result);
    }
    /**
     * 推送商品图片新增
     * @param array $param
     * @return mixed
     */
    public function productImageAdd(array $param) 
    {
        $product_id = $param['product_id'];
        $pic_url    = $param['pic_url'];
        $requestParam = [
            'method' => 'productImageAdd',
            'data'   => [
                'product_id'    => $product_id,
                'pic_url'       => $pic_url,
            ],
        ];
        $result = $this->execute($requestParam);
        if( $result["code"] != Normal::SUC ) {
            return Normal::returnCode(Normal::FAIL, "上次商品图片地址失败【{$result['msg']}】",$result);
        }
        return Normal::returnCode(Normal::SUC, "图片上传成功",$result);
    }
    
    /**
     * 推送商品图片删除
     * @param array $param
     * @return mixed
     */
    public function productImageDelete(array $param) 
    {
        $product_id = $param['product_id'];
        $pic_ids    = $param['pic_ids'];
        $requestParam = [
            'method' => 'productImageDelete',
            'data'   => [
                'product_id'    => $product_id,
                'pic_ids'       => $pic_ids,
            ],
        ];
        $result = $this->execute($requestParam);
        if( $result["code"] != Normal::SUC ) {
            return Normal::returnCode(Normal::FAIL, "productImageDelete失败【{$result['msg']}】",$result);
        }
        return Normal::returnCode(Normal::SUC, "图片删除成功",$result);
    }
    
    /**
     * 上传图片资源
     * @param string $redirect_url
     * @param string $image_path
     * @return mixed
     */
    public function uploadImageSource( $redirect_url = '', $image_path = '')
    {
        try {
            $filename = __DIR__.'/'.date("YmdHis").'_'.rand().'_'.uniqid('fenqile').'.jpg';
            //读取图片资源
            $image_soure = file_get_contents($image_path);
            //写入本地指定路径(用完之后删除)
            chmod(__DIR__,777);
            file_put_contents($filename, $image_soure);
            $result  = $this->uploadImageCurl($redirect_url, $filename);
            
            //token获取出来的地址
            unlink($filename);
            if( isset($result["retcode"]) && $result["retcode"] == 0 ) {
                return Normal::returnCode(Normal::SUC,"图片上传成功",$result);                
            }
            return Normal::returnCode(Normal::FAIL,"图片上传失败".$result["retmsg"],$result);
        } catch ( \Exception $th) {
            return Normal::returnCode(Normal::FAIL,"图片上传操作失败【{$th->getMessage()}{$th->getLine()}{$th->getFile()}】");
        }
    }
    
    /**
     * 上次图片请求
     * @param string $url
     * @param string $image
     */
    public function uploadImageCurl(string $url,string $image)
    {
        $start = microtime(true);
        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL             => $url,
            CURLOPT_RETURNTRANSFER  => true,
            CURLOPT_ENCODING        => '',
            CURLOPT_MAXREDIRS       => 10,
            CURLOPT_TIMEOUT         => 30,
            CURLOPT_FOLLOWLOCATION  => true,
            CURLOPT_HTTP_VERSION    => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST   => 'POST',
            CURLOPT_POSTFIELDS      => [
                'files'=> new \CURLFILE($image)
            ],
        ));
        $response = curl_exec($curl);
        curl_close($curl);
        
        //写入日志
        MicroServiceLog::instance()->addLog([
            'interface_code'    => $this->account.'_uploadImageCurl',
            'request_url'       => $url,
            'request_param'     => json_encode(['files'=>$image],JSON_UNESCAPED_UNICODE),
            'response_code'     => 200,
            'response_data'     => $response,
            'req_used_time'     => bcsub((string)microtime(true),$start,3),
        ]);
        return @json_decode($response,true);
    }
    
    /**
     * 推送商品sku
     * @param array $sku_add_data
     * @return mixed
     */
    public function skuAdd( array $data = [])
    {
        $_extra = [
            "feature"       => $this->config["sku_feature"],
            "delivery_time" => $this->config["delivery_time"],
            "sku_property"  => $this->config["sku_property"],
        ];
        $requestParam = [
            'method' => 'skuAdd',
            'data'   => array_merge($data,$_extra),
        ];
        return $this->execute($requestParam);
    }
    
    /**
     * 推送sku数量
     * @param array $params
     * @return mixed
     */
    public function skuQuantityUpdate(array $param) 
    {
        $data = [
            "sku_id"     => $param['sku_id'],
            "quantity"   => $param['num'],
            "type"       => 1,
        ];
        //组装推送上游数据
        $requestParam = [
            'method' => 'skuQuantityUpdate',
            'data'   => $data,
        ];
        return $this->execute($requestParam);
    }
    
    /**
     * 推送sku详情
     * @param array $params
     * @return mixed
     */
    public function skuDetailUpdate(array $param) 
    {
         $data = [
            "sku_id"          => $param['sku_id'],
            "parameter[text]" => $param['description'],
        ];
        //组装推送上游数据
        $requestParam = [
            'method' => 'skuDetailUpdate',
            'data'   => $data,
        ];
        return $this->execute($requestParam);
    }
    
    /**
     * 获取上传图片地址token
     * @param array $param
     */
    public function getUploadImageSourceToken($param = []) 
    {
        /* $requestParam = [
            'method' => 'getToken',
        ];
        $result_gettoken = $this->tokenExecute($requestParam);
        if( $result_gettoken["code"] == Normal::SUC ) 
        {
            $redirect_url = $result_gettoken["data"]["redirect_url"];
            return Normal::returnCode(Normal::SUC,"获取成功",$redirect_url);
        }
        return $result_gettoken; */
        
        $redis = redis();
        $cache_key = $this->account."_token_cache_redirect_url";
        $redirect_url = $redis->get($cache_key);
        if( empty($redirect_url)) 
        {
            $requestParam = [
                'method' => 'getToken',
            ];
            $result_token = $this->tokenExecute($requestParam);
            if( $result_token["code"] != Normal::SUC ) {
                return $result_token;
            }
            $redirect_url = $result_token["data"]["redirect_url"];
            $redis->set($cache_key,$redirect_url,60);
        }
        return Normal::returnCode(Normal::SUC,"获取成功",$redirect_url);
    }
  
    /**
     * 签名
     * @param array $param
     */
    private function getSign($param = []) 
    {
        ksort($param);
        $arr = "";
        foreach ($param as $k => $v) {
            $arr .= "{$k}={$v}&";
        }
        $arr .= "partner_key=" . $this->config["partner_key"];
        $param["sign"] = md5($arr);
        return $param;
    }
    
    /**
     * 获取token
     * @param array $param
     */
    private function getTokenSign($param = [])
    {
        ksort($param);
        $arr = "";
        foreach ($param as $k => $v) {
            $arr .= "{$k}={$v}&";
        }
        $arr .= "partner_key=" . $this->config["partner_key"];
        $sign = md5($arr);
        return $sign;
    }
    
    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    private function tokenExecute( $param = [])
    {
        $method             = $param["method"];
        $url                = $this->config["tokenUrl"];
        $data = [];
        $data["partner_id"] = $this->config["partner_id"];
        $data["timestamp"]  = time();
        $data["format"]     = "json";
        $data["v"]          = "1.0";
        $data["sign"]       = $this->getTokenSign($data);
        $response           = http::postJsonCurl($url,$data);
        $response           = @json_decode($response,true);
        //处理成功
        if (isset($response['error_response'])) {
            return Normal::returnCode(Normal::FAIL, $response['error_response']['sub_msg'] ?? "请求失败");
        }
        return Normal::returnCode(Normal::SUC, "获取成功", $response);
    }
    
    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function execute($param = []) 
    {
        $method                      = $param["method"];
        $url                         = $this->config["baseurl"];
        $param["data"]["method"]     = $this->routeMap[$method];
        $param["data"]["partner_id"] = $this->config["partner_id"];
        $param["data"]["v"]          = "1.0";
        $param["data"]["format"]     = "json";
        $param["data"]["timestamp"]  = time();
        $data                        = $this->getSign($param["data"]);
        $start                       = microtime(true);
        $response                    = Http::postJsonCurl($url, $data);
        $used_time                   = bcsub((string)microtime(true), $start,3);
        //写入日志
        MicroServiceLog::instance()->addLog([
            'interface_code'    => $this->account.'_'.$method,
            'request_url'       => $url,
            'request_param'     => json_encode($data,JSON_UNESCAPED_UNICODE),
            'response_code'     => 200,
            'response_data'     => $response,
            'req_used_time'     => $used_time,
        ]);
        $result   = @json_decode($response,true);
        if( empty($result) || isset($result['error_response'])) {
            $result = empty($result) ? ['error'=>$response] : $result;
            $erroMsg = json_encode($result,JSON_UNESCAPED_UNICODE);
            return Normal::returnCode(Normal::FAIL,"处理失败【{$erroMsg}】",$result);
        }
        return Normal::returnCode(Normal::SUC,"处理成功",$result);
    }
}